package com.lfs.adapter.base.virtual.util;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.lfs.adapter.config.ApplicationContextConfig;
import com.lfs.adapter.service.GameOrderInfoService;
import com.lfs.base.util.CollectionUtils;
import com.lfs.common.cache.redis.base.MapCache;
import com.lfs.common.constant.CommonConstants;
import com.lfs.common.constant.Constant;
import com.lfs.interfaces.authToken.service.AppAuthTokenService;
import com.lfs.interfaces.dto.ResultReturn;
import com.lfs.interfaces.model.AppAuthToken;
import com.lfs.interfaces.model.ChannelSupplier;
import com.lfs.interfaces.model.dto.OrderCharge;
import com.lfs.interfaces.model.dto.OrderDto;
import com.lfs.interfaces.model.dto.OrderNotifyDto;
import com.lfs.interfaces.model.vo.ChargeVo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.net.URLDecoder;
import java.util.List;

public class VirtualHttpUtil {

    private static final Logger logger = LoggerFactory.getLogger(VirtualHttpUtil.class);

    @Resource
    private ChannelSupplier config;

    private GameOrderInfoService gameOrderInfoService;

    private AppAuthTokenService appAuthTokenService;

    private MapCache mapCache;

    /**
     * 构造方法
     *
     * @param config
     *            config是通道供应商信息，由页面配置
     */
    public VirtualHttpUtil(ChannelSupplier config) {
        this.config = config;
        this.gameOrderInfoService = ApplicationContextConfig.getBean(GameOrderInfoService.class);
        this.appAuthTokenService = ApplicationContextConfig.getBean(AppAuthTokenService.class);
        this.mapCache = ApplicationContextConfig.getBean(MapCache.class);
    }

    public ResultReturn<ChargeVo> submitOrder(OrderDto order) {
        ResultReturn<ChargeVo> resp = new ResultReturn<>();
        ChargeVo vo = new ChargeVo();
        vo.setApplyTime(Constant.getDateTime());
        vo.setReqStreamId(order.getDownOrderNo());
        vo.setBalance(order.getBalance());
        vo.setOrderNo(order.getOrderNo());
        vo.setChargeNumBalance(new BigDecimal(0));
        // 我方订单号
        String orderNo = order.getOrderNo();
        String makeOrderUrl = config.getMakeOrderUrl();
        String notifyUrl = config.getNotifyUrl();
        String returnUrl = config.getFree1();
        AppAuthToken appAuthToken = null;
        String privateKey =null;
        String publicKey = null;
        String aliPayAppId = null;
        try {

            // 1.从redis获取
            List<AppAuthToken> appTokenList =(List<AppAuthToken>)mapCache.hget(Constant.HASH_APP_AUTH_LIST,Constant.HASH_APP_AUTH_LIST);
            // 2.redis不存在
            if (CollectionUtils.isEmpty(appTokenList)) {
                // 从数据库获取
                appTokenList = appAuthTokenService.getAppIdAndToken(null);
            }
            if (CollectionUtils.isNotEmpty(appTokenList)) {
                appAuthToken = appTokenList.get(0);
                publicKey = appAuthToken.getAppPublicKey();
                privateKey = appAuthToken.getAppPrivateKey();
                aliPayAppId = appAuthToken.getDevelopAppId();
                appTokenList.remove(0);
            }else{
                logger.info("获取到的收款人账号列表为空!");
                order.setErrorCode("9999" + "|"
                        + "获取到的收款人账号列表为空");
                order.setRemark("充值提交失败");
                order.setState(1);
                order.setAccountBalance(new BigDecimal(0));
                order.setUpOrderNo("");
                order.setCheckState(1);
                resp.setStatus(CommonConstants.RESP_CHARGE_FAIL).setData(vo,order).setMsg("充值提交失败");
                return resp;
            }
            // 存入数据库
            mapCache.hset(Constant.HASH_APP_AUTH_LIST, Constant.HASH_APP_AUTH_LIST, appTokenList);
            logger.info("从app列表中获取收款账号={}",appAuthToken.getAgtAppId());

            AlipayClient alipayClient = new DefaultAlipayClient(makeOrderUrl, aliPayAppId, privateKey, "json", "utf-8", publicKey, "RSA2"); //获得初始化的AlipayClient

            AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();//创建API对应的request类
            request.putOtherTextParam("app_auth_token", appAuthToken.getAppAuthToken());
            request.setNotifyUrl(notifyUrl);
            request.setReturnUrl(returnUrl);
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("out_trade_no",orderNo); //我方订单号
            jsonObject.put("total_amount",order.getChargeMoney()); //订单金额
            jsonObject.put("subject","PAYMENT COLLECTION");  // 订单标题
            jsonObject.put("timeout_express","15m");  //订单允许的最晚付款时间
            jsonObject.put("seller_id",appAuthToken.getAgtAppId());
            jsonObject.put("enable_pay_channels","balance,moneyFund,bankPay,debitCardExpress");
            request.setBizContent(jsonObject.toJSONString());
            AlipayTradePrecreateResponse response = alipayClient.execute(request);
            logger.info("支付宝同步创建下单接口返回{}:",response);
            if(response.isSuccess()){
                order.setErrorCode("200" + "|" + URLDecoder.decode("充值提交成功", "UTF-8"));
                order.setRemark("提交充值成功");
                order.setState(2);
                order.setAccountBalance(new BigDecimal(0));
                order.setUpOrderNo("");
                order.setCheckState(0);
                order.setOrderNo(orderNo);
                order.setQrCode(response.getQrCode());
                order.setChargeAddr(appAuthToken.getAgtAppAccount());
                vo.setChargeNumBalance(order.getAccountBalance());
                resp.setStatus(CommonConstants.RESP_CHARGE_HANDLE).setMsg("充值提交成功").setData(vo, order);
            } else {
                // 失败
                order.setErrorCode(response.getCode() + "|" + response.getMsg() +"|" + response.getSubCode()  + "|" + response.getSubMsg());
                order.setRemark("订单创建失败");
                order.setState(1);
                order.setAccountBalance(new BigDecimal(0));
                order.setUpOrderNo("");
                order.setCheckState(1);
                order.setChargeAddr(appAuthToken.getAgtAppAccount());
                resp.setStatus(CommonConstants.RESP_CHARGE_FAIL).setData(vo,order).setMsg("订单创建失败");
            }
        } catch (Exception e) {
            logger.error("Alipay上游异常信息：" + e.toString());
            resp.setStatus(CommonConstants.RESP_CHARGE_HANDLE).setData(vo, order).setMsg("提交上游出现异常");
        }


        return resp;
    }

    public String notify(String orderNo, String status, String upOrderNo) {
        String result = "Success";
        try {
            OrderCharge order = new OrderCharge();
            order.setOrderNo(orderNo);
            // order.setUpOrderNo(upOrderNo);
            List<OrderCharge> orders = gameOrderInfoService.getValidOrderForConfirmByBuscodeAndOrderNo(order);
            if (CollectionUtils.isNotEmpty(orders)) {
                OrderCharge orderInfo = orders.get(0);
                OrderNotifyDto orderNotify = new OrderNotifyDto();
                orderNotify.setAgtPhone(orderInfo.getAgtPhone());
                orderNotify.setReqStreamId(orderInfo.getDownOrderNo());
                orderNotify.setOrderNo(orderNo);
                orderNotify.setPrice(orderInfo.getPrice());

                orderInfo.setOutMoney(orderInfo.getOutMoney());
                orderInfo.setProfit(orderInfo.getProfit());
                OrderDto orderDto = new OrderDto();
                orderDto.setId(orderInfo.getId());
                orderDto.setOrderNo(orderInfo.getOrderNo());
                orderDto.setOutMoney(orderInfo.getOutMoney());
                orderDto.setProfit(orderInfo.getProfit());
                orderDto.setAgtNo(orderInfo.getAgtNo());
                orderDto.setChargeAddr(orderInfo.getChargeAddr());
                orderDto.setChargeMoney(orderInfo.getChargeMoney());
                orderDto.setUpOrderNo(upOrderNo == null ? "" : upOrderNo);
                if ("00".equals(status)) {
                    // 成功
                    orderDto.setState(0);
                    orderDto.setRemark("充值成功|回调");
                    gameOrderInfoService.updateOrderAfterNotify(orderDto);
                    result = "Success";
                    // 回写回调表
                    if (orderNotify.getReqStreamId() != null && orderNotify.getReqStreamId() != "") {
                        orderNotify.setState(0);
                        gameOrderInfoService.sendNotify(orderNotify);
                    }
                } else if ("01".equals(status)) {
                    // 失败，修改订单状态
                    orderDto.setState(1);
                    orderDto.setRemark("充值失败|回调");
                    gameOrderInfoService.updateOrderAfterNotify(orderDto);
                    result = "Success";
                    // 回写回调表
                    if (orderNotify.getReqStreamId() != null && orderNotify.getReqStreamId() != "") {
                        orderNotify.setState(1);
                        gameOrderInfoService.sendNotify(orderNotify);
                    }
                }
            } else {
                result = "Success";
            }
        } catch (Exception e) {
            logger.error(e.getMessage());
            result = "Exception";
        }
        return result;
    }
	
}
